/*
 *    Copyright (c) 2018-2025, boss All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * Redistributions of source code must retain the above copyright notice,
 * this list of conditions and the following disclaimer.
 * Redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution.
 * Neither the name of the boss developer nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 * Author: boss
 */
package com.hopes.bizz.line.pipe.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hopes.bizz.common.core.util.CoordinateSystemUtils;
import com.hopes.bizz.common.core.validate.ValidatorUtils;
import com.hopes.bizz.line.constant.enums.ParkLineSysDictEnum;
import com.hopes.bizz.line.pipe.dto.CoordinateDTO;
import com.hopes.bizz.line.pipe.dto.LinePipelineExcelDTO;
import com.hopes.bizz.line.pipe.entity.LinePipeEntity;
import com.hopes.bizz.line.pipe.entity.LinePipelineEntity;
import com.hopes.bizz.line.pipe.mapper.LinePipelineMapper;
import com.hopes.bizz.line.pipe.service.LinePipeService;
import com.hopes.bizz.line.pipe.service.LinePipelineService;
import com.hopes.bizz.line.pipe.vo.LinePipelineExcelVO;
import com.hopes.bizz.line.pipe.vo.LinePipelineVO;
import com.hopes.bizz.line.pipe.vo.PipeLineStatisticVO;
import com.hopes.boss.admin.api.resolver.DictResolver;
import com.hopes.boss.common.core.exception.BizException;
import com.hopes.boss.common.entity.ValidateImportBO;
import com.hopes.boss.common.excel.vo.ErrorMessage;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 管线
 *
 * @author pig
 * @date 2024-02-21 21:45:43
 */
@Service
@RequiredArgsConstructor
public class LinePipelineServiceImpl extends ServiceImpl<LinePipelineMapper, LinePipelineEntity> implements LinePipelineService {

    private final LinePipeService linePipeService;

    @Override
    public IPage<LinePipelineVO> pageVo(Page page, LambdaQueryWrapper<LinePipelineEntity> wrapper) {
        final Page<LinePipelineEntity> selectPage = getBaseMapper().selectPage(page, wrapper);
        final List<Long> pipeLineIdList = selectPage.getRecords().stream().map(LinePipelineEntity::getId).collect(Collectors.toList());
        if (CollUtil.isEmpty(pipeLineIdList)) {
            return new Page<>(selectPage.getCurrent(), selectPage.getSize(), selectPage.getTotal(), selectPage.searchCount());
        }
        final List<LinePipeEntity> linePipeList = linePipeService.list(
                Wrappers.<LinePipeEntity>lambdaQuery()
                        .in(LinePipeEntity::getPipelineId, pipeLineIdList));
        final Map<Long, List<LinePipeEntity>> listMap = linePipeList.stream().filter(e ->
                ObjUtil.isNotNull(e.getPipelineId())).collect(Collectors.groupingBy(LinePipeEntity::getPipelineId));
        final List<LinePipelineVO> collect = selectPage.getRecords().stream().map(e -> {
            final LinePipelineVO linePipelineVO = new LinePipelineVO();
            BeanUtils.copyProperties(e, linePipelineVO);
            linePipelineVO.setLinePipeList(listMap.get(e.getId()));
            return linePipelineVO;
        }).collect(Collectors.toList());
        final Page<LinePipelineVO> voPage = new Page<>(selectPage.getCurrent(), selectPage.getSize(), selectPage.getTotal(), selectPage.searchCount());
        voPage.setRecords(collect);
        return voPage;
    }

    @Override
    public PipeLineStatisticVO pipeLineStatistic(List<CoordinateDTO> coordinateList) {
        return linePipeService.pipeStatistic(linePipeService.queryByArea(coordinateList));
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean removeBatchByIds(Collection<?> list) {
        final long count = linePipeService.count(Wrappers.<LinePipeEntity>lambdaQuery().in(LinePipeEntity::getPipelineId, list));
        if (count > 0) {
            throw new BizException("存在关联的管段信息，不可删除！");
        }
        return removeBatchByIds(list, DEFAULT_BATCH_SIZE);
    }

    @Override
    public ValidateImportBO<LinePipelineExcelDTO> validateImport(List<LinePipelineExcelDTO> excelDTOList) {
        ValidateImportBO<LinePipelineExcelDTO> bo = new ValidateImportBO<>();
        List<ErrorMessage> errorMessageList = new ArrayList<>();
        List<LinePipelineExcelDTO> saveList = new ArrayList<>();
        int successNum = 0;
        int failedNum = 0;

        for (LinePipelineExcelDTO linePipelineExcelDTO : excelDTOList) {
            final String validateRes = ValidatorUtils.importValidateEntity(linePipelineExcelDTO);
            if (StrUtil.isEmpty(validateRes)) {
                successNum++;
                saveList.add(linePipelineExcelDTO);
            } else {
                failedNum++;
                errorMessageList.add(new ErrorMessage(linePipelineExcelDTO.getLineNum(), new HashSet<>(){
                    private static final long serialVersionUID = 1544007667186208650L;
                    {
                        add(validateRes);
                    }
                }));
            }
        }

        bo.setErrorMessages(errorMessageList);
        bo.setSaveList(saveList);
        bo.setSuccessNum(successNum);
        bo.setFailedNum(failedNum);
        return bo;
    }

    @Override
    public LinePipelineEntity importDtoToEntity(LinePipelineExcelDTO excelDto) {
        LinePipelineEntity entity= new LinePipelineEntity();
        BeanUtils.copyProperties(excelDto, entity);
        if (StrUtil.isNotBlank(excelDto.getEmbedTypeStr())) {
            entity.setEmbedType(DictResolver.getItemValueByLabel(ParkLineSysDictEnum.line_embed_type, excelDto.getEmbedTypeStr()));
        }
        if (StrUtil.isNotBlank(excelDto.getLineMaterialStr())) {
            entity.setLineMaterial(DictResolver.getItemValueByLabel(ParkLineSysDictEnum.line_material_type, excelDto.getLineMaterialStr()));
        }
        return entity;
    }

    @Override
    public LinePipelineExcelVO exportEntityToVo(LinePipelineEntity entity) {
        LinePipelineExcelVO excelVO = new LinePipelineExcelVO();
        BeanUtils.copyProperties(entity, excelVO);
        return excelVO;
    }


}
